/*****************************************************
*
*               COPYRIGHT (c) 2017-2019 Hargic Corporation
*                         All Rights Reserved
*
* The source code contained or described herein and all documents
* related to the source code ("Material") are owned by Hargic
* Corporation or its licensors.  Title to the Material remains
* with Hargic Corporation or its suppliers and licensors.
*
* The Material is protected by worldwide copyright and trade secret
* laws and treaty provisions. No part of the Material may be used,
* copied, reproduced, modified, published, uploaded, posted, transmitted,
* distributed, or disclosed in any way except in accordance with the
* applicable license agreement.
*
* No license under any patent, copyright, trade secret or other
* intellectual property right is granted to or conferred upon you by
* disclosure or delivery of the Materials, either expressly, by
* implication, inducement, estoppel, except in accordance with the
* applicable license agreement.
*
* Unless otherwise agreed by Hargic in writing, you may not remove or
* alter this notice or any other notice embedded in Materials by Hargic
* or Hargic's suppliers or licensors in any way.
*
** Author: shengda.huang
** Date: 2019-03-23
*
*****************************************************/

/***** Include files ********************************/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>

/***** Defines **************************************/
#define BUTTON     24
#define LED        4

/***** Define structure *****************************/

/***** Define constant ******************************/

/***** Define global ********************************/
int button_irq_num = 0;
bool led_status = 1;

/***** Define Prototype of functions ****************/
MODULE_AUTHOR("ted huang <tednick@163.com>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Gpio irq test!!\n");

/**
 * @brief
 * @param  None
 * @retval None
 */
static irqreturn_t button_irq_handle(int irq, void *dev_id)
{
	int value;

    value = gpio_get_value(BUTTON);
    printk(KERN_INFO "Enter irq %d button %d\n", irq, value);
    if(0 == led_status)
    {
        gpio_set_value(LED, 1);
        led_status = 1;
    }
    else
    {
        led_status = 0;
        gpio_set_value(LED, 0);
    }
    return (irqreturn_t)IRQ_HANDLED;
}

static int gpio_config(void)
{
    int ret = 0;
    if(!gpio_is_valid(BUTTON) || !gpio_is_valid(LED))
    {
        printk(KERN_ALERT "Gpio is invalid!\n");
        return -ENODEV;
    }
    gpio_request(BUTTON, "button");
    gpio_direction_input(BUTTON);
    gpio_set_debounce(BUTTON, 20 * 1000);

    button_irq_num = gpio_to_irq(BUTTON);
    printk(KERN_INFO "NUM = %d", button_irq_num);
    ret = request_irq(button_irq_num,
                    (irq_handler_t)button_irq_handle,
                    IRQF_TRIGGER_RISING,
                    "BUTTON1",
                    NULL);
    printk(KERN_INFO "GPIO_TEST: The interrupt request result is: %d\n", ret);

    gpio_request(LED, "LED");
    gpio_direction_output(LED, 1);
    gpio_set_value(LED, 1);

    // ret = gpio_export(BUTTON, false);
    // printk(KERN_INFO "gpio_export ret %d\n", ret);

    return 0;
}

static void gpio_deconfig(void)
{
	// gpio_unexport(BUTTON);
	printk(KERN_INFO "gpio_unexport\n");
    gpio_direction_output(LED, 0);
    free_irq(button_irq_num, NULL);
    gpio_free(BUTTON);
    gpio_free(LED);
}

int __init gpio_irq_init(void)
{
    gpio_config();
    printk(KERN_INFO "gpio_irq_init!\n");
    return 0;
}

void __exit gpio_irq_exit(void)
{
    gpio_deconfig();
    printk(KERN_INFO "gpio_irq_exit!\n");
}

module_init(gpio_irq_init);
module_exit(gpio_irq_exit);

/* End of file */



